{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "## 4.5 线性代数 Linear Algebra\r\n",
    "\r\n",
    "`numpy` 模块中的函数/方法：\r\n",
    "\r\n",
    "+ `numpy.dot(array_1, array_2)`：函数，矩阵乘法\r\n",
    "+ `array_1.dot(array_2)`：类方法，矩阵乘法\r\n",
    "\r\n",
    "`numpy.linalg` 模块中的函数：\r\n",
    "\r\n",
    "+ `numpy.linalg.det(array)`：计算矩阵的行列式（Determinant）；\r\n",
    "+ `numpy.linalg.inv(array)`：计算逆矩阵（Inverse），必须为方阵（Square matrix）；\r\n",
    "+ `numpy.linalg.pinv(array)`：计算矩阵的 Moore-Penrose 伪逆（Pseudo-inverse）；\r\n",
    "+ `numpy.linalg.matrix_rank`：计算矩阵的秩（Rank）；\r\n",
    "+ `numpy.linalg.diag(array)`：以一维数组的形式，返回矩阵的对角线元素。或将一维数组转换为对角方阵；\r\n",
    "+ `numpy.linalg.trace(array)`：矩阵的迹，即对角线元素的和（Sum of the diagonal elements）；\r\n",
    "+ `numpy.linalg.eig(array)`：计算矩阵的特征值（Eigenvalue）与特征向量（Eigenvectors）；\r\n",
    "+ `numpy.linalg.qr(array)`：计算 QR 分解（QR decomposition）；\r\n",
    "+ `numpy.linalg.svd(array)`：计算 SVD 分解（Singular value decomposition, SVD），即奇异值分解；\r\n",
    "+ `numpy.linalg.solve(array)`：求解线性方程组 Ax=b，其中 A 为方阵；\r\n",
    "+ `numpy.linalg.lstsq(array)`：计算 Ax=b 的最小二乘解（Least-squares solution）；\r\n",
    "\r\n",
    "更多函数可以查阅 `numpy.linalg` 的说明（鼠标悬停在 “linalg”）"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "# 模块导入\r\n",
    "import os, sys\r\n",
    "sys.path.append(os.path.dirname(os.getcwd()))\r\n",
    "import numpy\r\n",
    "from dependency import arr_info"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "# 数组乘法与矩阵乘法\r\n",
    "\r\n",
    "ary1_1 = numpy.array([ [1, 2, 3], [4, 5, 6], [7, 8, 9] ])\r\n",
    "ary1_2 = numpy.array([ [6, 23, 5], [-1, 7, 4], [8, 9, 3] ])\r\n",
    "arr_info([ary1_1, ary1_2])\r\n",
    "\r\n",
    "# 数组乘法\r\n",
    "array_multiply = ary1_1 * ary1_2\r\n",
    "\r\n",
    "# 矩阵乘法\r\n",
    "matrix_multiply = numpy.dot(ary1_1, ary1_2)\r\n",
    "# matrix_multiply = ary1_1.dot(ary1_2)  # 等价写法\r\n",
    "\r\n",
    "arr_info([array_multiply, matrix_multiply])"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "# 矩阵基本运算\r\n",
    "\r\n",
    "# arr1_3 = numpy.arange(2,11).reshape(3,3)\r\n",
    "arr1_3 = numpy.array([ [1, 1, 3], [1, 2, 1], [3, 4, 6] ])\r\n",
    "\r\n",
    "arr_info([arr1_3])\r\n",
    "\r\n",
    "arr_det = numpy.linalg.det(arr1_3)      # 行列式\r\n",
    "arr_inv = numpy.linalg.inv(arr1_3)      # 求逆\r\n",
    "# arr_ = numpy.linalg.multi_dot(arr1_3)\r\n",
    "arr_dot_inv = numpy.rint(numpy.dot(arr1_3, arr_inv))    # 矩阵与其逆矩阵的积\r\n",
    "arr_rank = numpy.linalg.matrix_rank(arr1_3)\r\n",
    "\r\n",
    "arr_info([arr_det, arr_inv, arr_dot_inv, arr_rank])"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "# 特征值与特征向量（例题：《线性代数》同济大学出版社 P118）\r\n",
    "\r\n",
    "arr1_4 = numpy.array([ [-1, 1, 0], [-4, 3, 0], [1, 0, 2] ])\r\n",
    "\r\n",
    "arr_eig = numpy.linalg.eig(arr1_4)      # arr[0]特征值，arr[1]特征向量\r\n",
    "\r\n",
    "# 特征向量是以列向量的形式表示的，所以需要做一定的转换\r\n",
    "print(\"特征向量：\")\r\n",
    "print((arr_eig[1].T)[0])  # 转置（得到行向量）\r\n",
    "print(arr_eig[1][:,:1]) # 索引与切片（仍未列向量）\r\n",
    "\r\n",
    "# 验证特征方程：Aα = λα\r\n",
    "result_1 = numpy.dot(arr1_4, arr_eig[1][:,:1])  \r\n",
    "result_2 = arr_eig[0][0] * arr_eig[1][:,:1]\r\n",
    "\r\n",
    "arr_info([arr1_4, arr_eig[0], arr_eig[1], result_1, result_2])"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "# 求解线性方程组\r\n",
    "\r\n",
    "arr_A = numpy.array([ [1, 1, 2], [2, 1, -2], [1, -1, -4] ])     # 必须为方阵，后续查找Scipy中有无更好的解法\r\n",
    "arr_B = numpy.array([ 1, 2, 3 ])\r\n",
    "\r\n",
    "solvation = numpy.linalg.solve(arr_A, arr_B)\r\n",
    "\r\n",
    "arr_info([solvation])"
   ],
   "outputs": [],
   "metadata": {}
  }
 ],
 "metadata": {
  "orig_nbformat": 4,
  "language_info": {
   "name": "python",
   "version": "3.9.6",
   "mimetype": "text/x-python",
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "pygments_lexer": "ipython3",
   "nbconvert_exporter": "python",
   "file_extension": ".py"
  },
  "kernelspec": {
   "name": "python3",
   "display_name": "Python 3.9.6 64-bit ('DataAnalysis': venv)"
  },
  "interpreter": {
   "hash": "0fe90ac710750590bd916650f441b3b2233faa2658175d6302b22e90f225e38d"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}